package com.scalar.chiptrack.adaptor.tsmc;

import com.scalar.chiptrack.jobs.JobHandler;
import com.scalar.chiptrack.adaptor.AdaptorConstants;
import com.scalar.chiptrack.adaptor.AdaptorUtils;
import com.scalar.chiptrack.adaptor.ParserException;
import com.scalar.chiptrack.adaptor.ShippedLot;
import com.scalar.chiptrack.adaptor.dao.FabSortAdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.ShippedLotDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorRunInfo;
import com.scalar.chiptrack.utils.Logger;
import com.scalar.chiptrack.utils.StringUtils;
import com.scalar.ScalarException;

import java.util.HashMap;
import java.util.ArrayList;
import java.util.Iterator;
import java.io.File;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

/**
 * Created by IntelliJ IDEA.
 * User: Sudhakar
 * Date: Jun 14, 2007
 * Time: 8:31:02 PM
 */
public class TSMCFabDataParser extends JobHandler implements AdaptorConstants
{
    private static Logger m_parserLogger    = null;
    private String m_dataOutputDir          = null;
    private HashMap m_tsmcWipDataMap        = new HashMap();
    private HashMap m_tsmcShipDataMap       = new HashMap();

    public TSMCFabDataParser() throws ScalarException
    {
        try
        {
            m_dataOutputDir = AdaptorUtils.getDataOutputDir(VENDOR_NAME_TSMC, WIP_TYPE_FAB);
            AdaptorUtils.makeAllAdaptorDirs( m_dataOutputDir );
            m_parserLogger = AdaptorUtils.getDataParserLogger( m_dataOutputDir, VENDOR_NAME_TSMC);
            FabSortAdaptorDAO.setLogger(m_parserLogger);
            ShippedLotDAO.setLogger(m_parserLogger);
        }
        catch (ScalarException se)
        {
            log("ERROR!! ERROR!! ERROR!! Exception while loading TSMC WIP output directory details from database, Exception: " + se);
            throw se;
        }

    }
    /**
     *
     * @param args
     * @throws Exception
     */
    public static void main( String args[] ) throws Exception
    {
        new TSMCFabDataParser().execute();
    }

    /**
     *
     */
    public void execute() throws Exception
    {
        printVersionInfo();

        File doneDestDir = new File( m_dataOutputDir + "/done");

        File tsmcWipDataoutDir = new File( m_dataOutputDir );

        File[] fileList = tsmcWipDataoutDir.listFiles();

        if ( ( fileList == null ) || ( fileList.length <= 3 ) )
        {
            log( "No file found in directory: " + tsmcWipDataoutDir );
            System.out.println( "No file found in directory: " + tsmcWipDataoutDir );
            throw new ScalarException( "No file found in directory: " + tsmcWipDataoutDir + "----\n\n" );

        }

        String fileName             = null;
        String tempName             = null;
        ArrayList m_tsmcWipList     = null;
        ArrayList m_tsmcShipList    = null;
        ArrayList successFileList   = new ArrayList();
        boolean success             = true;

        try
        {
            for ( int i = 0; i < fileList.length; i++ )
            {

                if ( fileList[i].isDirectory() == true )
                {
                    continue;
                }

                tempName = fileList[i].getName();
                fileName = fileList[i].getAbsolutePath();

               if ( ( tempName != null ) && ( tempName.trim().startsWith( TSMCAdaptor.REAL_WIP_INFO_FILE_NAME ) ) )
                {
                    try
                    {
                        m_tsmcWipList = parseWipInfo( fileName );
                        successFileList.add( fileList[i] );
                    }
                    catch ( Exception e )
                    {
                        success = false;
                        log( "Exception while parsing and storing file: " + fileName + "\nException: " + e );
                        e.printStackTrace();
                        throw e;
                    }
                }
                if ( ( tempName != null ) && ( tempName.trim().startsWith( TSMCAdaptor.SHIPPING_FILE_NAME ) ) )
                {
                    try
                    {
                        m_tsmcShipList = parseShippingInfo( fileName );
                        if ( m_tsmcShipList != null )
                        {
                            getTSMCShipList( m_tsmcShipList );
                        }

                        successFileList.add( fileList[i] );
                    }
                    catch ( Exception e )
                    {
                        success = false;
                        log( "Exception while parsing and storing file: " + fileName + "\nException: " + e );
                        e.printStackTrace();
                        throw e;
                    }
                }
            }
        }
        catch ( Exception e )
        {
            success = false;
            log( "ERROR!! ERROR!! ERROR!! While parsing and storing File " + e );
            e.printStackTrace();
            throw e;
        }
        // to save the Fab lot tables
        try
        {
            if ( m_tsmcWipList.isEmpty() == false )
            {
                log( "Updating Fab Lot Information in to Intermediate table" );
                TSMCDAO.saveTSMCWipDetails( null, m_tsmcWipList );
            }
        }
        catch ( Exception e )
        {
            success = false;
            log( "ERROR!! ERROR!! ERROR!! Could not update Fab Data information into database: " + e );
            e.printStackTrace();
            throw e;
        }


       /* Updating lots from Wip fed and TSMC */
       try
        {
            m_tsmcWipDataMap = TSMCDAO.getTSMCFabList();
            
            log( " Updating Wip Fed TSMC Fab Lot Information in to  Fab lot Table" );
            FabSortAdaptorDAO.saveFabLot( null, m_tsmcWipDataMap.values().iterator(), WIP_TYPE_FAB, VENDOR_NAME_TSMC );
            m_tsmcWipDataMap.clear();
            m_tsmcWipDataMap = null;
        }
        catch( Exception e)
        {
            success = false;
            e.printStackTrace();
        }

        try
        {
            // Save shipping info -
            if ( m_tsmcShipDataMap.isEmpty() == false )
            {
                log( "Updating shipment Information" );
                ShippedLotDAO.saveShippedLot( null, m_tsmcShipDataMap.values().iterator() );
                m_tsmcShipDataMap.clear();
                m_tsmcShipDataMap = null;
            }
        }
        catch ( Exception e )
        {
            success = false;
            log( "ERROR!! ERROR!! ERROR!! Could not update TSMC Shipping information into database: " + e );
            e.printStackTrace();
            throw e;
        }

        // TO SEND THE NEW LOTS, NEW TRANSIT LOTS, NO PO LOTS, DISCREPANCY LOTS NOTIFICATIONS TO THE USER
        AdaptorDAO.sendAllNotifications( VENDOR_NAME_TSMC, true, true, false );

        // To Close the Drop Out Lots
        AdaptorDAO.closeDropOutLots( VENDOR_NAME_TSMC );

         int adaptor_id = AdaptorRunInfo.getLastRunAdaptorId( TSMCAdaptor.ADAPTOR_NAME, CONSTANT_ADAPTOR);

        // Update Adaptor_Run_Info table
        try
        {
            if ( success == true )
            {
                AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, TSMCAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
                System.out.println( "SUCCESSFULLY UPDATED IN THE DATABASE" );
            }
        }
        catch ( ScalarException se )
        {
            success = false; //As filES DATA SAVED , UPDATEING AS SUCCESS
            AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, TSMCAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
            log( "WARNING!! WARNING!! WARNING!! Could not update Adaptor run information, Exception: " + se );
            throw se;
        }
        // Move the successful files to 'done' directory
       if ( success )
       {
           AdaptorUtils.moveFilesToDone( successFileList, doneDestDir );
       }
    }//end of execute method

    /**
    * Reads, parses the file and saves into database
    */
    private  ArrayList parseWipInfo( String fileName ) throws Exception
    {
        if ( fileName == null ) throw new ScalarException( "Filename argument is null" );

        ArrayList wipInfoList       = new ArrayList();
        BufferedReader fileReader   = null;

        try
        {
            File wipInfoFile = new File( fileName );
            if ( wipInfoFile.exists() == false )
            {
                throw new ScalarException( fileName + " doesnt exist" );
            }

            System.out.println( "Found " + fileName );
            System.out.println( "Parsing the file for Product Information..." );

            fileReader = new BufferedReader( new FileReader( wipInfoFile ) );

            String line = null;
            TSMCLotStatus wipInfo = null;
            ArrayList errors = new ArrayList();

            fileReader.readLine();  // skip 1st line
            fileReader.readLine();  // skip 2nd line

            while ( ( line = fileReader.readLine() ) != null )
            {
                try
                {
                    wipInfo = parseWipInfoLine( line );
                }
                catch ( ParserException pe )
                {
                    wipInfo = null;
                    errors.add( pe.getMessage() );
                }
                if ( wipInfo != null )
                {
                    if( wipInfo.getCurrentStage() != null && !"SHIPPED".equalsIgnoreCase(wipInfo.getCurrentStage()))
                    {
                        wipInfoList.add( wipInfo );
                    }
                }
            }

            fileReader.close();
            fileReader = null;

            System.out.println( "Done parsing.." );

            if ( errors.isEmpty() == false )
            {   // Parser Errors, Send mail to ChipTrac System Administrator
                System.out.println( "\nFound errors... notifying system administrator..." );
                System.out.println( "done\n" );
            }
        }
        finally
        {
            if ( fileReader != null )
            {
                try
                {
                    fileReader.close();
                }
                catch ( IOException ignore )
                {
                }
            }
        }

        return wipInfoList;
    }
    /**
     * Parses each line into TSMCShippingInfo object
     *
     * @param line to parse
     * @return TSMCShippingInfo parsed data object
     *
     * @throws com.scalar.chiptrack.adaptor.ParserException if there is any problem parsing the line
     */
    private TSMCLotStatus parseWipInfoLine( String line ) throws ParserException
    {

        TSMCLotStatus wipInfo = null;

        if ( ( line == null ) || ( line.startsWith( "---" ) ) || ( line.trim().length() < 65 /*min length*/ ) )
        {
            return wipInfo;
        }

        try
        {
            String[] token = line.split(",");

            wipInfo = new TSMCLotStatus();

            for (int x = 0; x < token.length; x++)
            {
                if (token[x] != null && token[x].trim().length() > 0)
                {
                    switch (x)
                    {
                        case 0:
                            wipInfo.setCustomerProduct(token[x].trim());
                            break;
                        case 1:
                            wipInfo.setCurrentMfgPart(token[x].trim());
                            break;
                        case 2:
                            wipInfo.setTsmcLotID(token[x].trim());
                            break;
                        case 3:
                            wipInfo.setWaferFab(token[x].trim());
                            break;
                        case 4:
                            wipInfo.setWaferStartQty(token[x].trim());
                            break;
                        case 5:
                            wipInfo.setWaferStartDate(token[x].trim());
                            break;
                        case 6:
                            wipInfo.setCurrentStage(token[x].trim());
                            break;
                        case 7:
                            wipInfo.setWaferQty(token[x].trim());
                            break;
                        case 8:
                            wipInfo.setDieQty(token[x].trim());
                            break;
                        case 9:
                            wipInfo.setHoldFlag(token[x].trim());
                            break;
                        case 10:
                            wipInfo.setUpdateMode(token[x].trim());
                            break;
                        case 11:
                            wipInfo.setCustomerLotID(token[x].trim());
                            break;
                        case 12:
                            wipInfo.setPmFactFlow(token[x].trim());
                            break;
                        case 13:
                            wipInfo.setBackUpFab(token[x].trim());
                            break;
                        case 14:
                            wipInfo.setWaferID(token[x].trim());
                            break;
                    }
                }
            }
        }
        catch (Exception e)
        {
            System.out.println("Exception while parsing Wip Info: " + e);
            System.out.println("Line: " + line);
            throw new ParserException("Exception while parsing Wip Info: " + e + "\nLine: " + line, e);
        }

        return wipInfo;
    }
    /**
     * Reads, parses the file and saves into database
     */
    private  ArrayList parseShippingInfo( String fileName ) throws Exception
    {

        if ( fileName == null ) throw new ScalarException( "Filename argument is null" );

        ArrayList shippingInfoList = new ArrayList();
        BufferedReader fileReader = null;

        try
        {
            File shippingInfoFile = new File( fileName );
            if ( shippingInfoFile.exists() == false )
            {
                throw new ScalarException( fileName + " doesnt exist" );
            }

            System.out.println( "Found " + fileName );
            System.out.println( "Parsing the file for Product Information..." );

            fileReader = new BufferedReader( new FileReader( shippingInfoFile ) );

            String line = null;
            TSMCShippingInfo shippingInfo = null;
            ArrayList errors = new ArrayList();

            fileReader.readLine();  // skip 1st line
            fileReader.readLine();  // skip 2nd line

            while ( ( line = fileReader.readLine() ) != null )
            {

                try
                {
                    shippingInfo = parseShippingInfoLine( line );
                }
                catch ( ParserException pe )
                {
                    shippingInfo = null;
                    errors.add( pe.getMessage() );
                }

                if ( shippingInfo != null )
                {
                    shippingInfoList.add( shippingInfo );
                }
            }

            fileReader.close();
            fileReader = null;

            System.out.println( "Done parsing.." );

            if ( errors.isEmpty() == false )
            {   // Parser Errors, Send mail to ChipTrac System Administrator
                System.out.println( "\nFound errors... notifying system administrator..." );
                System.out.println( "done\n" );
            }
        }
        finally
        {
            if ( fileReader != null )
            {
                try
                {
                    fileReader.close();
                }
                catch ( IOException ignore )
                {
                }
            }
        }

        return shippingInfoList;
    }
    /**
     * Parses each line into TSMCShippingInfo object
     *
     * @param line to parse
     * @return TSMCShippingInfo parsed data object
     *
     * @throws com.scalar.chiptrack.adaptor.ParserException if there is any problem parsing the line
     */
    private TSMCShippingInfo parseShippingInfoLine( String line ) throws ParserException
    {

        TSMCShippingInfo shippingInfo = null;

        if ( ( line == null ) || ( line.startsWith( "---" ) ) || ( line.trim().length() < 70 /*min length*/ ) )
        {
            return shippingInfo;
        }

        String[] lineToken = line.split("\"");

        if (lineToken != null && lineToken.length > 1)
        {
            lineToken[1] = lineToken[1].replaceAll(",", "");
        }

        line = "";
        for (int i = 0; i < lineToken.length; i++)
        {
            line = line + lineToken[i];
        }

        try
        {
            String[] token = line.split(",");
            shippingInfo = new TSMCShippingInfo();

            for (int x = 0; x < token.length; x++)
            {
                if (token[x] != null && token[x].trim().length() > 0)
                {
                    switch (x)
                    {
                        case 0:
                            shippingInfo.setInvoiceDate(token[x].trim());
                            break;
                        case 1:
                            shippingInfo.setInvoiceNo(token[x].trim());
                            break;
                        case 2:
                            shippingInfo.setCustomerPO(token[x].trim());
                            break;
                        case 3:
                            shippingInfo.setCustomerProduct(token[x].trim());
                            break;
                        case 4:
                            shippingInfo.setTsmcProduct(token[x].trim());
                            break;
                        case 5:
                            shippingInfo.setUm(token[x].trim());
                            break;
                        case 6:
                            shippingInfo.setCustomerLotID(token[x].trim());
                            break;
                        case 7:
                            shippingInfo.setTsmcLotID(token[x].trim());
                            break;
                        case 8:
                            shippingInfo.setShipQty(token[x].trim());
                            break;
                        case 9:
                            shippingInfo.setComment(token[x].trim());
                            break;
                        case 10:
                            shippingInfo.setWaferQty(token[x].trim());
                            break;
                        case 11:
                            shippingInfo.setDieQty(token[x].trim());
                            break;
                        case 12:
                            shippingInfo.setShipTo(token[x].trim());
                            break;
                        case 13:
                            shippingInfo.setWaferID(token[x].trim());
                            break;
                    }
                }
            }

        }
        catch (Exception e)
        {
            System.out.println( "Exception while parsing Shipping Info: " + e );
            System.out.println( "Line: " + line );
            throw new ParserException( "Exception while parsing Shipping Info: " + e + "\nLine: " + line, e );
        }

        return shippingInfo;
    }
    /**
    *
    * @param shipdataList
    */
   private void getTSMCShipList( ArrayList shipdataList )
   {
       TSMCShippingInfo tsmcShipReport = null;
       ShippedLot shippedLot = null;

       String partNumber = null;
       String lotNumber  = null;
       String invoiceNo  = null;
       String shipDate   = null;

       Iterator iterator = shipdataList.iterator();

       while ( iterator.hasNext() )
       {
           tsmcShipReport = ( TSMCShippingInfo ) iterator.next();

           partNumber   = tsmcShipReport.getCustomerProduct();
           lotNumber    = tsmcShipReport.getTsmcLotID();
           invoiceNo    = tsmcShipReport.getInvoiceNo();
           shipDate     = tsmcShipReport.getInvoiceDate();

            if ( tsmcShipReport != null && tsmcShipReport.getTsmcLotID() != null && tsmcShipReport.getTsmcLotID().length() > 0 && tsmcShipReport.getWaferQty() != null
                && tsmcShipReport.getWaferQty().trim().length() > 0  )
            {

                shippedLot = ( ShippedLot ) m_tsmcShipDataMap.get( lotNumber + partNumber + invoiceNo + shipDate );

                if ( shippedLot == null )
                {
                    shippedLot = new ShippedLot();
                    m_tsmcShipDataMap.put( lotNumber + partNumber + invoiceNo + shipDate, shippedLot );
                }
                int quantity = 0;
                if ( shippedLot.getShipQty() != null )
                {
                   try
                   {
                       quantity = Integer.parseInt( shippedLot.getShipQty() );
                   }
                   catch ( NumberFormatException ignore )
                   {
                   }
                   try
                   {
                       quantity += Integer.parseInt( tsmcShipReport.getWaferQty() );
                   }
                   catch ( NumberFormatException ignore )
                   {
                   }
                }
                else
                {
                   try
                   {
                       quantity = Integer.parseInt( tsmcShipReport.getWaferQty() );
                   }
                   catch ( NumberFormatException ignore )
                   {
                   }
                }
                shippedLot.setLotNumber( lotNumber );
                shippedLot.setPartNumber( partNumber );
                shippedLot.setShipDate( StringUtils.formatDate( shipDate, "MM/dd/yyyy", "MM/dd/yyyy" ) );
                shippedLot.setShipQty( quantity +"" );
                shippedLot.setInvoiceNumber( tsmcShipReport.getInvoiceNo() );
                shippedLot.setCurrentLocation( LOCATION_TYPE_FAB );
                shippedLot.setCustomerPO( tsmcShipReport.getCustomerPO() );
                shippedLot.setNextLocation( tsmcShipReport.getShipTo() );
                shippedLot.setVendorName( VENDOR_NAME_TSMC );
                shippedLot.setWaferID( tsmcShipReport.getWaferID() );
                shippedLot.setFabLotNumber( lotNumber );
           }

       }
   }
    /**
     *
     * @param message
     */
    private static void log( String message )
    {

        if ( message == null ) return;

        if ( m_parserLogger != null )
        {
            synchronized ( m_parserLogger )
            {
                m_parserLogger.logDebug( message + LINE_SEPARATOR );
            }
        }
        else
        {
            System.out.println( message );
        }
    }
    /**
     *
     */
    private void printVersionInfo()
    {
           String info = "\n\n+----------- Running TSMC FAB Data Parser on " + new java.util.Date( System.currentTimeMillis() ) + " -------------+\n" +
                    "\n+---------------------------------------------------------------+\n" +
                    "+                                                                \n" +
                    "+            TSMC FAB Data Interpreter - Beta          \n" +
                    "+                                                                \n" +
                    "+    Copy Right (C) 2007 - ScalarSoft Inc., All rights reserved.  \n" +
                    "+                                                                \n" +
                    "+---------------------------------------------------------------+\n" ;
           System.out.println( info );
           log( info );
    } //end of printVersionInfo
}
